Skip to content

docs(ui): use storybook-i18n addon for locale switching#2125

Open
cylewaitforit wants to merge 1 commit intonpmx-dev:mainfrom
cylewaitforit:sb-storybook-i18n
Open

docs(ui): use storybook-i18n addon for locale switching#2125
cylewaitforit wants to merge 1 commit intonpmx-dev:mainfrom
cylewaitforit:sb-storybook-i18n

Conversation

@cylewaitforit
Copy link
Contributor

@cylewaitforit cylewaitforit commented Mar 17, 2026

🔗 Linked issue

Related: #1964

🧭 Context

This adds the storybook-i18n for locale switching in the npmx storybook.

📚 Description

This allows stories that have been configured with a translation to be viewed with different translations.

@vercel
Copy link

vercel bot commented Mar 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs.npmx.dev Ready Ready Preview, Comment Mar 19, 2026 0:05am
npmx.dev Ready Ready Preview, Comment Mar 19, 2026 0:05am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
npmx-lunaria Ignored Ignored Mar 19, 2026 0:05am

Request Review

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 809025db-a27f-4aa4-8852-25947cdf8032

📥 Commits

Reviewing files that changed from the base of the PR and between 542b245 and c1f5529.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .storybook/main.ts
  • .storybook/preview.ts
  • app/components/Link/Link.stories.ts
  • package.json
  • pnpm-workspace.yaml
✅ Files skipped from review due to trivial changes (2)
  • pnpm-workspace.yaml
  • package.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • .storybook/main.ts
  • app/components/Link/Link.stories.ts
  • .storybook/preview.ts

📝 Walkthrough

Walkthrough

Added Storybook i18n support: appended storybook-i18n to .storybook/main.ts addons and added storybook-i18n to dev dependencies and pnpm workspace catalog. Updated .storybook/preview.ts to introduce initialGlobals (locale: 'en-US' and locales), remove the locale globalType, cache the active $i18n instance for channel-driven LOCALE_CHANGED updates, and adjust the decorator to treat locale as optional and set locale in created(). Updated Link component stories to provide explicit args and use custom render functions that call $t(...) for translated content.

Possibly related PRs

  • docs(ui): add stories for Link #1732: Modifies the same Link component stories (adds render functions and changes story args) — strong overlap in story-level i18n changes.
  • feat: add storybook #1270: Changes .storybook/main.ts and .storybook/preview.ts with i18n/locale-related Storybook configuration — directly related to addon and preview updates.

Suggested reviewers

  • danielroe
  • JReinhold
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly explains the purpose: adding storybook-i18n for locale switching in Storybook, allowing stories with translations to be viewed with different translations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.storybook/preview.ts (1)

22-26: Avoid any for the i18n instance and narrow before calling setLocale.

Line 22 and Lines 92-96 currently bypass type checks; a narrow interface here keeps the locale bridge safe and explicit.

💡 Suggested refactor
-let currentI18nInstance: any = null
+type StorybookI18nInstance = {
+  setLocale: (locale: string) => void | Promise<void>
+}
+let currentI18nInstance: StorybookI18nInstance | null = null
@@
-          currentI18nInstance = this.$i18n
+          currentI18nInstance =
+            this.$i18n && typeof this.$i18n.setLocale === 'function'
+              ? (this.$i18n as StorybookI18nInstance)
+              : null
@@
-          if (locale && this.$i18n) {
-            this.$i18n.setLocale(locale)
+          if (locale && currentI18nInstance) {
+            void currentI18nInstance.setLocale(locale)
           }

As per coding guidelines, "Ensure you write strictly type-safe code, for example by ensuring you always check when accessing an array value by index".

Also applies to: 91-96


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a584aa74-dd82-4f31-b2eb-5c2635be10b0

📥 Commits

Reviewing files that changed from the base of the PR and between ad2b174 and 542b245.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .storybook/main.ts
  • .storybook/preview.ts
  • app/components/Link/Link.stories.ts
  • package.json
  • pnpm-workspace.yaml

Comment on lines +21 to +27
// Subscribe to locale changes from storybook-i18n addon (once, outside decorator)
let currentI18nInstance: any = null
addons.getChannel().on('LOCALE_CHANGED', (newLocale: string) => {
if (currentI18nInstance) {
currentI18nInstance.setLocale(newLocale)
}
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

For Storybook 10 using storybook/preview-api, is channel.off(eventName, listener)the supported way to avoid duplicate listeners during HMR afterchannel.on(eventName, listener)?

💡 Result:

Yes. In Storybook 10, addons.getChannel() returns a Node.js EventEmitter-compatible channel, so removing a listener with channel.off(eventName, listener) is part of the supported API surface. [1]

Storybook’s own addon examples use the exact pattern to avoid duplicate subscriptions (subscribe with on, then unsubscribe with off in cleanup), e.g. channel.on(EVENTS.REQUEST, handleRequest) paired with channel.off(EVENTS.REQUEST, handleRequest). [2]

Also, Storybook’s @storybook/preview-api testing utilities model the channel with an explicit off(eventId, listener) method, reinforcing that off is the intended unsubscribe call. [3]

Important: you must pass the same function reference to off that you passed to on (i.e., don’t inline a new lambda each HMR pass). [2]

Sources: [1] (storybook.js.org) [2] (storybook.js.org) [3] (tessl.io)

Citations:


De-register the locale listener before re-registering it to avoid duplicate handlers during HMR.

Line 23 adds a module-scope LOCALE_CHANGED listener; on preview HMR reloads this can stack handlers and trigger repeated setLocale calls. Use channel.off() with the same function reference to clean up before re-subscribing.

💡 Suggested fix
-let currentI18nInstance: any = null
-addons.getChannel().on('LOCALE_CHANGED', (newLocale: string) => {
+let currentI18nInstance: any = null
+const channel = addons.getChannel()
+const onLocaleChanged = (newLocale: string) => {
   if (currentI18nInstance) {
     currentI18nInstance.setLocale(newLocale)
   }
-})
+}
+channel.off?.('LOCALE_CHANGED', onLocaleChanged)
+channel.on('LOCALE_CHANGED', onLocaleChanged)

Also consider typing currentI18nInstance to improve type safety.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Subscribe to locale changes from storybook-i18n addon (once, outside decorator)
let currentI18nInstance: any = null
addons.getChannel().on('LOCALE_CHANGED', (newLocale: string) => {
if (currentI18nInstance) {
currentI18nInstance.setLocale(newLocale)
}
})
// Subscribe to locale changes from storybook-i18n addon (once, outside decorator)
let currentI18nInstance: any = null
const channel = addons.getChannel()
const onLocaleChanged = (newLocale: string) => {
if (currentI18nInstance) {
currentI18nInstance.setLocale(newLocale)
}
}
channel.off?.('LOCALE_CHANGED', onLocaleChanged)
channel.on('LOCALE_CHANGED', onLocaleChanged)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant